package org.springblade.modules.charger.service.impl;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import lombok.AllArgsConstructor;
import org.springblade.core.log.exception.ServiceException;
import org.springblade.core.mp.base.BaseServiceImpl;
import org.springblade.modules.charger.excel.ChargerExcel;
import org.springblade.modules.charger.mapper.ChargerMapper;
import org.springblade.modules.charger.pojo.entity.ChargerEntity;
import org.springblade.modules.charger.pojo.entity.ChargerOrderEntity;
import org.springblade.modules.charger.pojo.req.StartingChargeRequestBody;
import org.springblade.modules.charger.pojo.req.UpdateFirmwareRequestBody;
import org.springblade.modules.charger.pojo.vo.ChargerVO;
import org.springblade.modules.charger.pojo.vo.Inside.ChargingOrderJsonVO;
import org.springblade.modules.charger.service.IChargerOrderService;
import org.springblade.modules.charger.service.IChargerService;
import org.springblade.ocpp.WebSocketServer;
import org.springblade.ocpp.domain.req.DataTransferRequest;
import org.springblade.ocpp.domain.req.RemoteStartTransactionRequest;
import org.springblade.ocpp.domain.req.RemoteStopTransactionRequest;
import org.springblade.ocpp.domain.req.UpdateFirmwareRequest;
import org.springblade.ocpp.send.DelaySend;
import org.springblade.ocpp.send.RemoteStopTransactionSend;
import org.springblade.ocpp.send.UpdateFirmwareSend;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * 充电桩管理 服务实现类
 *
 * @author lhb
 * @since 2024-10-04
 */
@Service
@AllArgsConstructor
public class ChargerServiceImpl extends BaseServiceImpl<ChargerMapper, ChargerEntity> implements IChargerService {

	private final IChargerOrderService chargerOrderService;

	@Override
	public IPage<ChargerVO> selectChargerPage(IPage<ChargerVO> page, ChargerVO charger) {
		return page.setRecords(baseMapper.selectChargerPage(page, charger));
	}


	@Override
	public List<ChargerExcel> exportCharger(Wrapper<ChargerEntity> queryWrapper) {
		List<ChargerExcel> chargerList = baseMapper.exportCharger(queryWrapper);
		//chargerList.forEach(charger -> {
		//	charger.setTypeName(DictCache.getValue(DictEnum.YES_NO, Charger.getType()));
		//});
		return chargerList;
	}

	@Override
	public boolean startCharge(StartingChargeRequestBody requestBody) {

		// 判断设备是否在线
		if (!WebSocketServer.webSocketMap.containsKey(requestBody.getChargerSn())) {
			throw new ServiceException("充电桩已离线,无法操作");
		}
		ChargerEntity charger = this.getById(requestBody.getId());

		// 发送消息给充电桩
		// 准备发送 RemoteStartTransaction 信息给充电桩准备开始充电
		RemoteStartTransactionRequest delay = new RemoteStartTransactionRequest(0);
		delay.setSid(charger.getChargerSn());
		delay.setConnectorId(requestBody.getGunNum());
		delay.setIdTag(IdUtil.fastSimpleUUID());
		RemoteStartTransactionRequest.ChargingProfileDTO chargingProfile = new RemoteStartTransactionRequest.ChargingProfileDTO();
		chargingProfile.setChargeProfileId(1);
		chargingProfile.setChargingProfileKind("Relative");
		chargingProfile.setChargingProfilePurpose("TxProfile");
		RemoteStartTransactionRequest.ChargingProfileDTO.ChargingScheduleDTO chargingSchedule = new RemoteStartTransactionRequest.ChargingProfileDTO.ChargingScheduleDTO();
		chargingSchedule.setChargingRateUnit("A");
		List<RemoteStartTransactionRequest.ChargingProfileDTO.ChargingScheduleDTO.ChargingSchedulePeriodDTO> chargingSchedulePeriod = new ArrayList<>();
		RemoteStartTransactionRequest.ChargingProfileDTO.ChargingScheduleDTO.ChargingSchedulePeriodDTO chargingSchedulePeriodDTO = new RemoteStartTransactionRequest.ChargingProfileDTO.ChargingScheduleDTO.ChargingSchedulePeriodDTO();
		chargingSchedulePeriodDTO.setLimit(60);
		chargingSchedulePeriodDTO.setStartPeriod(0);
		chargingSchedulePeriod.add(chargingSchedulePeriodDTO);
		chargingSchedule.setChargingSchedulePeriod(chargingSchedulePeriod);
		chargingProfile.setChargingSchedule(chargingSchedule);
		delay.setChargingProfile(chargingProfile);
		// 设置到延时队列, 延迟后发送消息到充电桩
		DelaySend.put(delay);

		// 发送充电站资料给客户端
		DataTransferRequest dataTransferRequest = new DataTransferRequest(1);
		dataTransferRequest.setSid(charger.getChargerSn());
		dataTransferRequest.setVendorId("Spiro");
		dataTransferRequest.setMessageId("ChargingProfile");

		JSONObject data = new JSONObject();
		data.put("chargingProfileId", 1);
		data.put("connectorId", requestBody.getGunNum());
		data.put("TargetSOC", requestBody.getTargetSOC());
		data.put("format", "Raw");
		data.put("unit", "percent");
		dataTransferRequest.setData(Base64.encode(data.toString()));

		DelaySend.put(dataTransferRequest);
		return true;
	}

	@Override
	public boolean stopCharge(StartingChargeRequestBody requestBody) {

		if (!WebSocketServer.webSocketMap.containsKey(requestBody.getChargerSn())) {
			throw new ServiceException("充电桩已离线,无法操作");
		}

		// 查询充电桩信息
		ChargerEntity charger = this.getById(requestBody.getId());
		if (null == charger) {
			throw new ServiceException("充电桩不存在");
		}

		Long orderId = null;
		// 查询关联的订单信息
		ChargingOrderJsonVO chargingOrderJsonVO = JSONObject.parseObject(charger.getChargingOrder(), ChargingOrderJsonVO.class);
		if (1 == requestBody.getGunNum()) {
			orderId = Long.valueOf(chargingOrderJsonVO.getGunOne());
		} else if (2 == requestBody.getGunNum()) {
			orderId = Long.valueOf(chargingOrderJsonVO.getGunTwo());
		}
		if (null == orderId) {
			throw new ServiceException(StrUtil.format("枪{}未在充电", requestBody.getGunNum()));
		}

		// 判断订单是否已停止
		ChargerOrderEntity chargerOrder = chargerOrderService.getById(orderId);
		if (null == chargerOrder) {
			throw new ServiceException(StrUtil.format("订单{}不存在", orderId));
		}
		if (2 == chargerOrder.getStatus()) {
			throw new ServiceException(StrUtil.format("订单{}已经结束", orderId));
		}

		// 发送停止充电请求给充电桩
		RemoteStopTransactionRequest remoteStopTransactionRequest = new RemoteStopTransactionRequest();
		remoteStopTransactionRequest.setTransactionId(orderId);
		remoteStopTransactionRequest.setSid(charger.getChargerSn());
		RemoteStopTransactionSend.send(remoteStopTransactionRequest);
		return true;
	}

	@Override
	public boolean updateFirmware(UpdateFirmwareRequestBody requestBody) {
		// TODO 查找固件升级包
		UpdateFirmwareRequest request = new UpdateFirmwareRequest();
		JSONObject data = new JSONObject();
		data.put("type", "");
		data.put("url", "https://114.115.210.66:9000/ocppManager/static/OTA-0508.zip");
		request.setLocation(data.toString());
		request.setRetrieveDate(DateUtil.format(LocalDateTime.now(), DatePattern.UTC_PATTERN));
		UpdateFirmwareSend.send(request);
		return true;
	}

}
